﻿using System;
using System.Text.Json.Serialization;

namespace Sgr.Workspace.Models
{
    /// <summary>
    /// 当前在线用户信息
    /// </summary>
    public class CurrentOnlineUserInfo
    {
        /// <summary>
        /// 当前在线用户数
        /// </summary>
        [JsonInclude]
        public int Current { get; private set; }

        /// <summary>
        /// 上一个周期的在线用户数
        /// </summary>
        [JsonInclude]
        public int Previous { get; private set; }

        /// <summary>
        /// 更新时间
        /// </summary>
        [JsonInclude]
        public DateTime UpdateTime { get; private set; } = DateTime.UtcNow;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public CurrentOnlineUserInfo()
        {
        }

        /// <summary>
        /// 带初始值的构造函数
        /// </summary>
        /// <param name="current">当前在线用户数</param>
        /// <param name="previous">上一周期在线用户数</param>
        public CurrentOnlineUserInfo(int current, int previous = 0)
        {
            SetValues(current, previous);
        }

        /// <summary>
        /// 计算变化率
        /// </summary>
        /// <param name="current">当前值</param>
        /// <param name="previous">上一周期值</param>
        /// <returns>变化率百分比</returns>
        public static double CalculateChangeRate(int current, int previous)
        {
            if (previous == 0)
                return current > 0 ? 100.0 : 0.0;

            return (double)(current - previous) / previous * 100.0;
        }

        /// <summary>
        /// 更新到新周期的数据
        /// </summary>
        /// <param name="newCurrent">新周期的当前在线用户数</param>
        /// <remarks>
        /// 此方法将当前值移动到Previous，并设置新的Current值
        /// 适用于周期性更新场景
        /// </remarks>
        public void UpdateToNewPeriod(int newCurrent)
        {
            if (newCurrent < 0)
                throw new ArgumentException("在线用户数不能为负数", nameof(newCurrent));

            Previous = Current;
            Current = newCurrent;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 设置当前周期和上一周期的值
        /// </summary>
        /// <param name="current">当前在线用户数</param>
        /// <param name="previous">上一周期在线用户数</param>
        /// <remarks>
        /// 适用于同时获取到当前和上一周期数据的场景
        /// </remarks>
        public void SetValues(int current, int previous)
        {
            if (current < 0)
                throw new ArgumentException("当前在线用户数不能为负数", nameof(current));
            if (previous < 0)
                throw new ArgumentException("上一周期在线用户数不能为负数", nameof(previous));

            Current = current;
            Previous = previous;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 获取变化率（百分比，正数表示增长，负数表示下降）
        /// </summary>
        /// <returns>变化率百分比</returns>
        public double GetChangeRate()
        {
            return CalculateChangeRate(Current, Previous);
        }

        /// <summary>
        /// 获取变化趋势描述
        /// </summary>
        /// <returns>趋势描述字符串</returns>
        public string GetTrendDescription()
        {
            return GetChangeRate() switch
            {
                > 0 => "增长",
                < 0 => "下降",
                _ => "稳定"
            };
        }

        /// <summary>
        /// 获取格式化的变化率字符串
        /// </summary>
        /// <param name="decimalPlaces">小数位数</param>
        /// <returns>格式化的变化率（带%符号）</returns>
        public string GetFormattedChangeRate(int decimalPlaces = 1)
        {
            var sign = GetChangeRate() > 0 ? "+" : "";
            return string.Format("{0}{1:F" + decimalPlaces + "}%", sign, GetChangeRate());
        }

        /// <summary>
        /// 重置所有数据
        /// </summary>
        public void Reset()
        {
            Current = 0;
            Previous = 0;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 返回对象的字符串表示
        /// </summary>
        public override string ToString()
        {
            return $"当前: {Current}, 上期: {Previous}, 变化: {GetFormattedChangeRate()}, 更新: {UpdateTime:yyyy-MM-dd HH:mm:ss}";
        }
    }
}